#include "SymmetricKeyMemory.h"

#include <assert.h>
#include <QCryptographicHash>
#include <QByteArray>
#include <QString>

namespace kryptos { namespace cryptography {

SymmetricKeyMemory::SymmetricKeyMemory()
{
}

SymmetricKeyMemory::SymmetricKeyMemory(const char* bytes, int len, bool reuseWhenFinished)
    : SymmetricKey(reuseWhenFinished)
{
    assert(bytes);
    m_key.resize(len);
    m_key.assign(bytes, bytes+len);
    m_size = len;
}

SymmetricKeyMemory::~SymmetricKeyMemory()
{
    m_key.clear();
}

void SymmetricKeyMemory::change(const char* bytes, int len, bool reuseWhenFinished)
{
    assert(bytes);

    reset();
    m_reuse = reuseWhenFinished;
    m_key.clear();
    m_key.resize(len);
    m_key.assign(bytes, bytes+len);
    m_size = len;

    m_id = QString(QCryptographicHash::hash(QByteArray(bytes, len), QCryptographicHash::Sha1)).toStdString();
}

bool SymmetricKeyMemory::isValid()
{
    bool valid = m_size > 0;

    if (valid && !m_reuse)
        valid = m_offset < m_size;

    return valid;
}

std::vector<char> SymmetricKeyMemory::nextBytes(int len)
{
    std::vector<char> bytes;

    int bytesLeft = m_size - m_offset;
    if (bytesLeft < len)
    {
        if (m_reuse)
        {
            bytes.resize(bytesLeft);
            bytes.assign(m_key.begin() + m_offset, m_key.begin() + m_offset + bytesLeft);
            m_offset = 0;//move offset back to begining

            // start over copying from begining
            for (int i=m_offset; i<(unsigned long long)len - bytesLeft; i++)
            {
                // start over copying from begining
                if (m_offset == m_size)
                    m_offset = 0;

                bytes.push_back(*(m_key.begin()+m_offset));
                m_offset++;
            }
        }
    }
    else
    {
        bytes.resize(len);
        bytes.assign(m_key.begin() + m_offset, m_key.begin() + m_offset + len);
        m_offset += len;
    }

    return bytes;
}

}}
